﻿package me.zhengjie.common.utils

import org.springframework.util.DigestUtils
import java.nio.charset.StandardCharsets
import java.util.*
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.DESKeySpec
import javax.crypto.spec.IvParameterSpec


/**
 * 加密
 * @author Kuki Wu
 * @date 2024-11-23
 */
object EncryptUtils {
    private const val strKey = "Passw0rd"
    private const val strParam = "Passw0rd"

    /**
     * 对称加密
     */
    @JvmStatic
    @Throws(Exception::class)
    fun desEncrypt(source: String?): String? {
        if (source == null || source.length == 0) {
            return null
        }
        val cipher = Cipher.getInstance("DES/CBC/PKCS5Padding")
        val desKeySpec = DESKeySpec(strKey.toByteArray(StandardCharsets.UTF_8))
        val keyFactory = SecretKeyFactory.getInstance("DES")
        val secretKey = keyFactory.generateSecret(desKeySpec)
        val iv = IvParameterSpec(strParam.toByteArray(StandardCharsets.UTF_8))
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv)
        return byte2hex(
            cipher.doFinal(source.toByteArray(StandardCharsets.UTF_8))
        ).uppercase(Locale.getDefault())
    }

    @JvmStatic
    private fun byte2hex(inStr: ByteArray): String {
        var stmp: String
        val out = StringBuilder(inStr.size * 2)
        for (b in inStr) {
            stmp = Integer.toHexString(b.toInt() and 0xFF)
            if (stmp.length == 1) {
                // 如果是0至F的单位字符串，则添加0
                out.append("0").append(stmp)
            } else {
                out.append(stmp)
            }
        }
        return out.toString()
    }

    @JvmStatic
    private fun hex2byte(b: ByteArray): ByteArray {
        require(b.size % 2 == 0) { "长度不是偶数" }
        val b2 = ByteArray(b.size / 2)
        var n = 0
        while (n < b.size) {
            val item = String(b, n, 2)
            b2[n / 2] = item.toInt(16).toByte()
            n += 2
        }
        return b2
    }

    /**
     * 对称解密
     */
    @JvmStatic
    @Throws(Exception::class)
    fun desDecrypt(source: String?): String? {
        if (source == null || source.length == 0) {
            return null
        }
        val src = hex2byte(source.toByteArray())
        val cipher = Cipher.getInstance("DES/CBC/PKCS5Padding")
        val desKeySpec = DESKeySpec(strKey.toByteArray(StandardCharsets.UTF_8))
        val keyFactory = SecretKeyFactory.getInstance("DES")
        val secretKey = keyFactory.generateSecret(desKeySpec)
        val iv = IvParameterSpec(strParam.toByteArray(StandardCharsets.UTF_8))
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv)
        val retByte = cipher.doFinal(src)
        return String(retByte)
    }

    /**
     * 密码加密
     */
    @JvmStatic
    fun encryptPassword(password: String): String {
        return DigestUtils.md5DigestAsHex(password.toByteArray())
    }
}
